Creating a package
How to create a package for pip
To create a distribution package, additional files beyond the implementation are needed. It is recommended to have a project directory named after the package, with implementation files and directories in a subdirectory src.
Modern Python packaging is based on a pyproject.toml file in the project directory.
Defining metadata
Metadata are provided in a TOML ‘table’ project:
[project]Name of the distribution package. To avoid being changed by normalization, it should be lowercase and contain only
a–z,0–9, and-.name = "mkernel"Version in the format of PEP 440. It can also be extracted from the implementation files, see below.
version = "1.0.0"A one-line description. Could include a different stylization of the package name.
description = "MKernel: A Jupyter Kernel for Matlab"Pointer to a README file in the same directory. Markdown (
.md) and ReStructuredText (.rst) are automatically recognized.readme = "README.md"Required version of Python. Should at least specify whether Python 2 or 3.
requires-python = ">=3.3"Names of authors. Emails can be specified with an additional key
email.authors = [{name = "Carsten Allefeld"}]If separate from authors, there can be an additional entry
maintainers.Freely chosen keywords characterizing the package.
keywords = ["jupyter", "kernel", "matlab"]Classifiers characterizing the project, from a defined list.
classifiers = [ "Development Status :: 5 - Production/Stable", "Framework :: Jupyter", "Intended Audience :: Science/Research", "Intended Audience :: Developers", "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)", "Programming Language :: Python :: 3", "Topic :: Scientific/Engineering" ]Packages this package depends on, specified according to PEP 508.
dependencies = [ "ipykernel", "matlabengine", "wurlitzer" ]URLs where further information can be found, as a sub-table. Normally
Homepageis sufficient, but separate entries forDocumentation,Repository, andChangelogare also supported.[project.urls] Homepage = "https://github.com/allefeld/mkernel"
In addition it is possible
- to point to a LICENSE file, but that is somewhat redundant with
classifiers, - to include optional dependencies,
- and to define entry points for command line and GUI scripts.
Additional features depending on a build backend
We here use hatchling.build, which has to be configured via the build-system table:
requires = ["hatchling"]
build-backend = "hatchling.build"Version information can be obtained from the implementation files. To do so, replace
version = "1.0.0"bydynamic = ["version"]and add
[tool.hatch.version] path = "src/mkernel/kernel.py"where the specified file has to contain a line of the form
__version__ = '1.0.0'.Non-implementation files (wheel subdirectory
{distribution}-{version}.data/) can be included in the package, e.g. a Jupyter kernel specification.[tool.hatch.build.targets.wheel.shared-data] "kernelspec/kernel.json" = "share/jupyter/kernels/mkernel/kernel.json"The entries of this table map paths within the project directory to paths within
{distribution}-{version}.data/data/, i.e. the data files part of the install scheme.
See also OS Integration Files in Python Packages.
Building
The simplest way to build the package into a wheel file is to run from the project directory:
pip wheel --no-deps .It is also implicitly built when installing from source (either a local directory or a git repository).
How to create a package for conda
TODO